﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using uCoreClasses;
using System.Runtime.Remoting.Messaging;
using StoreClientModule;
namespace DataManager
{
    public delegate void AsyncOp(object p, out object err);

    public struct CashRegistryCommit
    {
        public string fDate;
        public string fDenomination;
        public string fPcs;
        public string fOver;
    }
    public struct ChequeEntryCommit
    {
        public string acctName;
        public string bankName;
        public string dateReceived;
        public string checkNumber;
        public string amount;
        public string duedate;
        public string oldCheckNumber;
        public string ORNumber;
        public string InvoiceNumber;
        public string type;
        public string status;
    }
    public struct ExpensesEntryCommit
    {
        public string date;
        public string name;
        public string amount;
        public string type;
        public string id;
    }
    public struct ChargeInvoiceInfo
    {
        public string DateReceived;
        public string ReferenceNumber;
        public string AccountName;
        public string ORNumber;
        public string InvoiceNumber;
        public string Amount;
        public string CheckNumber;
        public string BankName;
        public string Mode;
        public string DueDate;

        public string Terms;
        public string Percentage;
        public string Balance;

        public string month;
        public string year;
        public bool all;
    }

    struct salesItem
    {
        public string invoice;
        public double amount;
        public string date;
    }
    struct paymentItems
    {
        public string invoice;
        public double amount;
    }
    struct paymentTerms
    {
        public string invoice;
        public string terms;
        public string percentage;

    }
    struct payments
    {
        public string invoice;
        public string date;
        public string or;
        public string checknumber;
        public string amount;
    }

    public class ChargeInvoiceRecords
    {
        int procCode = -1;

        DataTable pTable = new DataTable();
        DataTable pTable2 = new DataTable();

        string errorMsg = "";
        string date = "";
        string accntName = "";
        string bal = "";
        double totalBalance = 0;

        bool isExist = false;
        bool withRecord = false;

        public ChargeInvoiceInfo[] charge = new ChargeInvoiceInfo[0];
        //Sync op

        void pChargeInvoiceRecords(object p, out object err)
        {
            procCode = 5;
            string inp = (string)p;
            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);

                db.RecordQuery("SELECT * FROM tblsalesitem WHERE fInvoice = '" + inp + "'");
                if (db.Count > 0)
                {
                    pTable = new DataTable();
                    pTable.Columns.Add("Qty");
                    pTable.Columns.Add("Unit");
                    pTable.Columns.Add("Description");
                    pTable.Columns.Add("Unit Price");
                    pTable.Columns.Add("Amount");

                    for (int i = 0; i < db.Count; i++)
                    {
                        DataRow dr = pTable.NewRow();

                        dr["Qty"] = db.RecordAt(i, "fQty");
                        dr["Unit"] = db.RecordAt(i, "fUnit");
                        dr["Description"] = db.RecordAt(i, "fDescription");
                        dr["Unit Price"] = db.RecordAt(i, "fUnitPrice");
                        double amt = Double.Parse(db.RecordAt(i, "fQty")) * Double.Parse(db.RecordAt(i, "fUnitPrice"));
                        dr["Amount"] = Common.FormatCurrency(amt);

                        pTable.Rows.Add(dr);
                    }

                    db.RecordQuery("SELECT fAccountName, fDateReceived, fORNumber, fAmount, fCheckNumber FROM tblchargepayments WHERE fInvoiceNumber = '" + inp + "'");
                    pTable2 = new DataTable();
                    pTable2.Columns.Add("Date");
                    pTable2.Columns.Add("Account Name");
                    pTable2.Columns.Add("OR Number");
                    pTable2.Columns.Add("Check Number");
                    pTable2.Columns.Add("Amount");

                    for (int i = 0; i < db.Count; i++)
                    {
                        DataRow dr = pTable2.NewRow();

                        dr["Date"] = db.RecordAt(i, "fDateReceived");
                        dr["Account Name"] = db.RecordAt(i, "fAccountName");
                        dr["OR Number"] = db.RecordAt(i, "fORNumber");
                        dr["Check Number"] = db.RecordAt(i, "fCheckNumber");
                        dr["Amount"] = db.RecordAt(i, "fAmount");

                        pTable2.Rows.Add(dr);
                    }

                    db.RecordQuery("SELECT fDate, fSoldTo FROM tblsalesdetail WHERE fInvoice = '" + inp + "'");
                    date = db.RecordAt(0, "fDate");
                    accntName = db.RecordAt(0, "fSoldTo");

                    db.RecordQuery("SELECT * FROM tblChargeBalance WHERE fInvoice = '" + inp + "' AND fStatus = '1'");
                    if (db.Count == 1)
                    {
                        string percentage = db.RecordAt(0, "fPercentage");
                        string terms = db.RecordAt(0, "fTerms");
                        string duedate = db.RecordAt(0, "fDueDates");
                        double balance = double.Parse(db.RecordAt(0, "fBalance"));

                        DateTime oldDate, newDate, storeDate;
                        oldDate = DateTime.Parse(duedate);
                        newDate = DateTime.Parse(DateTime.Now.ToShortDateString());
                        storeDate = oldDate;
                        if (newDate > oldDate)
                        {
                            int cnt = newDate.Subtract(oldDate).Days;
                            if (cnt > int.Parse(terms))
                            {
                                if (int.Parse(terms) == 0) terms = "1";
                                int l = cnt / int.Parse(terms);
                                double per = (l * double.Parse(percentage)) / 100;
                                balance = balance + (balance * per);

                                int additionalDays = l * int.Parse(terms);
                                storeDate = oldDate.AddDays(additionalDays);
                            }
                            else
                            {
                                balance = balance + (balance * (double.Parse(percentage) / 100));
                                storeDate = oldDate.AddDays(int.Parse(terms));
                            }
                        }

                        db.Records[0]["fBalance"] = balance.ToString();
                        db.Records[0]["fDueDates"] = storeDate.ToShortDateString();
                        db.Update(ConflictOption.CompareRowVersion);

                        bal = balance.ToString();

                    }
                    isExist = true;
                }
                else
                {
                    isExist = false;
                    pTable = new DataTable();
                    pTable2 = new DataTable();
                    bal = "0.00";
                    date = "";
                    accntName = "";
                }
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                err = errorMsg;
            }
        }
        void pStatementOfAccount(object p, out object err)
        {
            procCode = 1;
            ChargeInvoiceInfo inp = (ChargeInvoiceInfo)p;

            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);
                //query all invoices from tblsalesitem
                db.RecordQuery("SELECT fInvoice, fQty, fUnitPrice FROM tblsalesitem");
                //struct for storing values
                salesItem[] si = new salesItem[db.Count];

                for (int i = 0; i < db.Count; i++)
                {
                    si[i].invoice = db.RecordAt(i, "fInvoice");
                    float qty = float.Parse(db.RecordAt(i, "fQty"));
                    float unitPrice = float.Parse(db.RecordAt(i, "fUnitPrice"));
                    si[i].amount = qty * unitPrice;
                }


                //query all invoices from tblsalesdetail
                if (inp.all == false)
                    db.RecordQuery("SELECT fInvoice, fDate, fRef, fPO FROM tblsalesdetail WHERE fSoldTo = '" + inp.AccountName + "' AND fInvoiceType = 'Charged' AND fDate LIKE '" + inp.month + "%" + inp.year + "' AND fRef LIKE 'B%'");
                else
                    db.RecordQuery("SELECT fInvoice, fDate, fRef, fPO FROM tblsalesdetail WHERE fSoldTo = '" + inp.AccountName + "' AND fInvoiceType = 'Charged' AND fDate LIKE '%" + inp.year + "' AND fRef LIKE 'B%'");
                int cnt = db.Count;
                if (cnt > 0)
                {
                    withRecord = true;
                    pTable = new DataTable();
                    pTable.Columns.Add("Date of Invoices");
                    pTable.Columns.Add("Invoice Number");
                    pTable.Columns.Add("Amount");
                    pTable.Columns.Add("P.O. Number");

                    salesItem[] siInvoice = new salesItem[db.Count];

                    for (int i = 0; i < cnt; i++)
                    {
                        DataRow dr = pTable.NewRow();
                        double amt = 0;

                        dr["Date of Invoices"] = db.RecordAt(i, "fDate");
                        dr["Invoice Number"] = db.RecordAt(i, "fInvoice");

                        string invoice = db.RecordAt(i, "fInvoice");
                        siInvoice[i].invoice = invoice;
                        siInvoice[i].date = db.RecordAt(i, "fDate");
                        //check invoice from the struct
                        for (int j = 0; j < si.Length; j++)
                        {
                            if (invoice.Equals(si[j].invoice))
                            {
                                amt += si[j].amount;
                            }
                        }

                        dr["Amount"] = Common.FormatCurrency(amt);
                        dr["P.O. Number"] = db.RecordAt(i, "fPO");

                        pTable.Rows.Add(dr);
                    }

                    //query all payments
                    db.RecordQuery("SELECT fAccountName, fDateReceived, fORNumber, fAmount, fCheckNumber, fInvoiceNumber FROM tblchargepayments");
                    int cnt2 = db.Count;

                    if (cnt2 > 0)
                    {
                        pTable2 = new DataTable();
                        pTable2.Columns.Add("Date");
                        pTable2.Columns.Add("Invoice Number");
                        pTable2.Columns.Add("OR Number");
                        pTable2.Columns.Add("Check Number");
                        pTable2.Columns.Add("Amount");

                        for (int i = 0; i < cnt2; i++)
                        {
                            for (int j = 0; j < siInvoice.Length; j++)
                            {
                                //check in the stored invoice of that account is equal to the invoice number of the payments
                                if (siInvoice[j].invoice.Equals(db.RecordAt(i, "fInvoiceNumber")))
                                {
                                    DataRow dr = pTable2.NewRow();

                                    dr["Date"] = db.RecordAt(i, "fDateReceived");
                                    dr["Invoice Number"] = db.RecordAt(i, "fInvoiceNumber");
                                    dr["OR Number"] = db.RecordAt(i, "fORNumber");
                                    dr["Check Number"] = db.RecordAt(i, "fCheckNumber");
                                    dr["Amount"] = db.RecordAt(i, "fAmount");

                                    pTable2.Rows.Add(dr);
                                }
                            }
                        }
                    }

                    string query = "";
                    int x = siInvoice.Length;
                    if (siInvoice.Length > 0)
                    {
                        query = "SELECT * FROM tblChargeBalance WHERE ";
                        for (int i = 0; i < siInvoice.Length; i++)
                        {
                            query = query + " (fInvoice = '" + siInvoice[i].invoice + "'";
                            if (i < x - 1)
                                query += " AND fStatus = '1') OR ";
                            else if (x == 1)
                                query += " AND fStatus = '1') ";
                            else
                                query += " AND fStatus = '1') ";
                        }
                    }
                    totalBalance = 0;
                    
                    db.RecordQuery(query);
                    int cnt3 = db.Count;
                    if (cnt3 > 0)
                    {
                        for (int i = 0; i < cnt3; i++)
                        {
                            double balance = double.Parse(db.RecordAt(i, "fBalance"));
                            totalBalance += balance;
                        }
                    }
                }
                else
                    withRecord = false;

                db.Disconnect();
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                err = errorMsg;
            }
        }

        //Async op
        void GenericCB(IAsyncResult ar)
        {
            //Obtain the Delegate
            AsyncOp ao = (AsyncOp)((AsyncResult)ar).AsyncDelegate;
            //Prepare output
            object err;
            //Wrap-up the output
            ao.EndInvoke(out err, ar);
            string er = (string)err;
            if (er.Equals(""))
            {
                OnProcessCompleted(er);
            }
            else
            {
                OnProcessError(er);
            }
        }

        //out
       
        public int ProcessCode
        {
            get { return procCode; }
        }
        public DataTable RecordTable
        {
            get { return pTable; }
        }
        public DataTable RecordTable2
        {
            get { return pTable2; }
        }
        public bool isExisting
        {
            get { return isExist; }
        }
        public string getDate
        {
            get { return date; }
        }
        public string getAccntName
        {
            get { return accntName; }
        }
        public string Balance
        {
            get { return bal; }
        }
        public string TotalBalance
        {
            get { return totalBalance.ToString(); }
        }
        public bool WithRecords
        {
            get { return withRecord; }
        }

        public void ciRecords(string invoice)
        {
            //Synchronous method to call.
            AsyncOp ao = new AsyncOp(pChargeInvoiceRecords);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);
            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(invoice, out er, ac, null);
        }
        public void StatementOfAccount(ChargeInvoiceInfo search)
        {
            //Synchronous method to call.
            AsyncOp ao = new AsyncOp(pStatementOfAccount);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);
            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(search, out er, ac, null);
        }


        //Events
        public delegate void MyEventHandler(string msg);
        public event MyEventHandler ProcessCompleted;
        public event MyEventHandler ProcessError;
        protected virtual void OnProcessCompleted(string msg)
        {
            if (ProcessCompleted != null) ProcessCompleted(msg);
        }
        protected virtual void OnProcessError(string msg)
        {
            if (ProcessError != null) ProcessError(msg);
        }
    }
    public class ChequeRecords
    {
        int procCode = -1;
        DataTable pTable = new DataTable();
        string errorMsg = "";

        bool isUpdated = false;
        bool isSaved = false;
        bool isDuplicate = false;

        //Sync op
        void pCheckDuplicate(object p, out object err)
        {
            procCode = 0;
            string inp = (string)p;
            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);
                db.RecordQuery("SELECT * FROM tblcheque WHERE fCheckNumber = '" + inp + "'");

                if (db.Count > 0)
                    isDuplicate = true;
                else
                    isDuplicate = false;
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                err = errorMsg;
            }
        }
        void pCommit(object p, out object err)
        {
            procCode = 2;
            ChequeEntryCommit[] inp = (ChequeEntryCommit[])p;

            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);
                db.RecordQuery("SELECT * FROM tblcheque");

                for (int i = 0; i < inp.Length; i++)
                {
                    DataRow dr = db.QueryTable.NewRow();
                    dr["fAccountName"] = inp[i].acctName;
                    dr["fBankName"] = inp[i].bankName;
                    dr["fDateReceived"] = inp[i].dateReceived;
                    dr["fCheckNumber"] = inp[i].checkNumber;
                    dr["fAmount"] = inp[i].amount;
                    dr["fDueDate"] = inp[i].duedate;

                    db.AddRecord(dr);
                    db.Update();

                    isSaved = true;
                }
                /*
                db.RecordQuery("SELECT * FROM tblchequereceipt");
                for (int i = 0; i < inp.Length; i++)
                {
                    if (inp[i].type.Equals("Charge"))
                    {
                        DataRow dr = db.QueryTable.NewRow();
                        dr["fAccountName"] = inp[i].acctName;
                        dr["fBankName"] = inp[i].bankName;
                        dr["fDateReceived"] = inp[i].dateReceived;
                        dr["fCheckNumber"] = inp[i].checkNumber;
                        dr["fAmount"] = inp[i].amount;
                        dr["fDueDate"] = inp[i].duedate;
                        dr["fORNumber"] = inp[i].ORNumber;
                        dr["fInvoiceNumber"] = inp[i].InvoiceNumber;

                        db.AddRecord(dr);
                        db.Update();
                    }
                }
                 */

            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                err = errorMsg;
            }
        }
        void pGetRecords(object p, out object er)
        {

            procCode = 1;

            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);
                db.RecordQuery("SELECT * FROM tblcheque");

                if (db.Count == 0)
                    errorMsg = "No Record/s Found";

                pTable = new DataTable();
                pTable.Columns.Add("Account Name");
                pTable.Columns.Add("Name of Bank");
                pTable.Columns.Add("Date Received");
                pTable.Columns.Add("Check Number");
                pTable.Columns.Add("Amount");
                pTable.Columns.Add("Status");
                pTable.Columns.Add("Due Date");

                for (int i = 0; i < db.Count; i++)
                {
                    DataRow dr = pTable.NewRow();

                    dr["Account Name"] = db.RecordAt(i, "fAccountName");
                    dr["Name of Bank"] = db.RecordAt(i, "fBankName");
                    dr["Date Received"] = db.RecordAt(i, "fDateReceived");
                    dr["Check Number"] = db.RecordAt(i, "fCheckNumber");
                    dr["Amount"] = db.RecordAt(i, "fAmount");
                    dr["Status"] = db.RecordAt(i, "fStatus");
                    dr["Due Date"] = db.RecordAt(i, "fDueDate");

                    pTable.Rows.Add(dr);
                }
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                er = errorMsg;
            }
        }
        void pUpdateRecords(object p, out object err)
        {
            procCode = 3;
            ChequeEntryCommit inp = (ChequeEntryCommit)p;

            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);

                db.RecordQuery("SELECT * FROM tblcheque WHERE fCheckNumber = '" + inp.oldCheckNumber + "'");
                if (db.Count == 1)
                {
                    db.QueryTable.Rows[0]["fAccountName"] = inp.acctName;
                    db.QueryTable.Rows[0]["fBankName"] = inp.bankName;
                    db.QueryTable.Rows[0]["fDateReceived"] = inp.dateReceived;
                    db.QueryTable.Rows[0]["fCheckNumber"] = inp.checkNumber;
                    db.QueryTable.Rows[0]["fAmount"] = inp.amount;
                    db.QueryTable.Rows[0]["fDueDate"] = inp.duedate;

                    db.Update(ConflictOption.CompareRowVersion);
                    isUpdated = true;
                }
                else
                    isUpdated = false;
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                err = errorMsg;
            }

        }
        void pUpdateStatus(object p, out object err)
        {
            procCode = 5;
            ChequeEntryCommit inp = (ChequeEntryCommit)p;

            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);

                db.RecordQuery("SELECT * FROM tblcheque WHERE fCheckNumber = '" + inp.checkNumber + "'");
                if (db.Count == 1)
                {
                    db.QueryTable.Rows[0]["fStatus"] = inp.status;
                    db.Update(ConflictOption.CompareRowVersion);
                    isUpdated = true;
                }
                else
                    isUpdated = false;
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                err = errorMsg;
            }

        }
        void pSearchStatusRecords(object p, out object err)
        {
            string status = (string)p;
            procCode = 6;
            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);
                db.RecordQuery("SELECT * FROM tblcheque WHERE fStatus = '" + status + "'");

                pTable = new DataTable();
                pTable.Columns.Add("Account Name");
                pTable.Columns.Add("Name of Bank");
                pTable.Columns.Add("Date Received");
                pTable.Columns.Add("Check Number");
                pTable.Columns.Add("Amount");
                pTable.Columns.Add("Due Date");


                for (int i = 0; i < db.Count; i++)
                {
                    DataRow dr = pTable.NewRow();

                    dr["Account Name"] = db.RecordAt(i, "fAccountName");
                    dr["Name of Bank"] = db.RecordAt(i, "fBankName");
                    dr["Date Received"] = db.RecordAt(i, "fDateReceived");
                    dr["Check Number"] = db.RecordAt(i, "fCheckNumber");
                    dr["Amount"] = db.RecordAt(i, "fAmount");
                    dr["Due Date"] = db.RecordAt(i, "fDueDate");

                    pTable.Rows.Add(dr);
                }


            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                err = errorMsg;
            }
        }
        void pSearchRecords(object p, out object err)
        {
            string date = (string)p;
            procCode = 4;
            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);
                db.RecordQuery("SELECT * FROM tblcheque WHERE fDateReceived = '" + date + "'");

                pTable = new DataTable();
                pTable.Columns.Add("Account Name");
                pTable.Columns.Add("Name of Bank");
                pTable.Columns.Add("Date Received");
                pTable.Columns.Add("Check Number");
                pTable.Columns.Add("Amount");
                pTable.Columns.Add("Due Date");


                for (int i = 0; i < db.Count; i++)
                {
                    DataRow dr = pTable.NewRow();

                    dr["Account Name"] = db.RecordAt(i, "fAccountName");
                    dr["Name of Bank"] = db.RecordAt(i, "fBankName");
                    dr["Date Received"] = db.RecordAt(i, "fDateReceived");
                    dr["Check Number"] = db.RecordAt(i, "fCheckNumber");
                    dr["Amount"] = db.RecordAt(i, "fAmount");
                    dr["Due Date"] = db.RecordAt(i, "fDueDate");

                    pTable.Rows.Add(dr);
                }


            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                err = errorMsg;
            }
        }

        //online
        void pSearchRecordsOnline(object p, out object err)
        {
            string date = (string)p;
            procCode = 4;
            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.oServer, Common.oDatabase, Common.oUID, Common.oPWD);

                if (date.Equals("All"))
                    db.RecordQuery("SELECT * FROM tblcheque");
                else
                    db.RecordQuery("SELECT * FROM tblcheque WHERE fDateReceived = '" + date + "'");


                pTable = new DataTable();
                pTable.Columns.Add("Account Name");
                pTable.Columns.Add("Name of Bank");
                pTable.Columns.Add("Date Received");
                pTable.Columns.Add("Check Number");
                pTable.Columns.Add("Amount");
                pTable.Columns.Add("Due Date");

                for (int i = 0; i < db.Count; i++)
                {
                    DataRow dr = pTable.NewRow();

                    dr["Account Name"] = db.RecordAt(i, "fAccountName");
                    dr["Name of Bank"] = db.RecordAt(i, "fBankName");
                    dr["Date Received"] = db.RecordAt(i, "fDateReceived");
                    dr["Check Number"] = db.RecordAt(i, "fCheckNumber");
                    dr["Amount"] = db.RecordAt(i, "fAmount");
                    dr["Due Date"] = db.RecordAt(i, "fDueDate");

                    pTable.Rows.Add(dr);
                }
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                err = errorMsg;
            }
        }
        //Async op
        void GenericCB(IAsyncResult ar)
        {
            //Obtain the Delegate
            AsyncOp ao = (AsyncOp)((AsyncResult)ar).AsyncDelegate;
            //Prepare output
            object err;
            //Wrap-up the output
            ao.EndInvoke(out err, ar);
            string er = (string)err;
            if (er.Equals(""))
            {
                OnProcessCompleted(er);
            }
            else
            {
                OnProcessError(er);
            }
        }

        public void GetRecords()
        {
            AsyncOp ao = new AsyncOp(pGetRecords);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object er;
            IAsyncResult ar = ao.BeginInvoke(null, out er, ac, null);
        }
        public void UpdateRecords(ChequeEntryCommit cec)
        {
            //Synchronous method to call.
            AsyncOp ao = new AsyncOp(pUpdateRecords);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);

            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(cec, out er, ac, null);
        }
        public void UpdateStatus(ChequeEntryCommit cec)
        {
            //Synchronous method to call.
            AsyncOp ao = new AsyncOp(pUpdateStatus);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);

            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(cec, out er, ac, null);
        }
        public void CheckDuplicate(string CheckNumber)
        {
            //Synchronous method to call.
            AsyncOp ao = new AsyncOp(pCheckDuplicate);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);
            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(CheckNumber, out er, ac, null);
        }
        public void Commit(ChequeEntryCommit[] cec)
        {
            //Synchronous method to call.
            AsyncOp ao = new AsyncOp(pCommit);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);
            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(cec, out er, ac, null);
        }
        public void SearchStatusRecords(string status)
        {
            AsyncOp ao = new AsyncOp(pSearchStatusRecords);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);

            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(status, out er, ac, null);
        }
        public void SearchRecords(string date)
        {
            AsyncOp ao = new AsyncOp(pSearchRecords);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);

            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(date, out er, ac, null);
        }

        //online
        public void SearchRecordsOnline(string date)
        {
            AsyncOp ao = new AsyncOp(pSearchRecordsOnline);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);

            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(date, out er, ac, null);
        }

        //out data
        public DataTable RecordTable
        {
            get { return pTable; }
        }
        public int ProcessCode
        {
            get { return procCode; }
        }
        public bool Updated
        {
            get { return isUpdated; }
        }
        public bool Saved
        {
            get { return isSaved; }
        }
        public bool Duplicate
        {
            get { return isDuplicate; }
        }
        //Events
        public delegate void MyEventHandler(string msg);
        public event MyEventHandler ProcessCompleted;
        public event MyEventHandler ProcessError;
        protected virtual void OnProcessCompleted(string msg)
        {
            if (ProcessCompleted != null) ProcessCompleted(msg);
        }
        protected virtual void OnProcessError(string msg)
        {
            if (ProcessError != null) ProcessError(msg);
        }
    }
    public class ExpensesRecords
    {
        int procCode = -1;
        DataTable pTable = new DataTable();
        string errorMsg = "";
        bool isUpdated = false;

        //Sync op
        void pGetRecords(object p, out object er)
        {
            procCode = 0;
            string date = DateTime.Now.Date.ToShortDateString();
            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);
                db.RecordQuery("SELECT * FROM tblexpenses WHERE fDate = '" + date + "'");

                pTable = new DataTable();

                pTable.Columns.Add("Expenses Name");
                pTable.Columns.Add("Amount");
                pTable.Columns.Add("Type");
                pTable.Columns.Add("Code");

                for (int i = 0; i < db.Count; i++)
                {
                    DataRow dr = pTable.NewRow();

                    dr["Expenses Name"] = db.RecordAt(i, "fExpensesName");
                    dr["Amount"] = db.RecordAt(i, "fExpensesAmount");
                    dr["Type"] = db.RecordAt(i, "fExpensesType");
                    dr["Code"] = db.RecordAt(i, "fID");

                    pTable.Rows.Add(dr);
                }
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                er = errorMsg;
            }
        }
        void pCommit(object p, out object err)
        {
            procCode = 1;
            ExpensesEntryCommit[] inp = (ExpensesEntryCommit[])p;

            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);
                db.RecordQuery("SELECT * FROM tblexpenses");

                for (int i = 0; i < inp.Length; i++)
                {
                    DataRow dr = db.QueryTable.NewRow();
                    dr["fExpensesName"] = inp[i].name;
                    dr["fExpensesAmount"] = inp[i].amount;
                    dr["fExpensesType"] = inp[i].type;
                    dr["fDate"] = inp[i].date;

                    db.AddRecord(dr);
                    db.Update();
                }
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                err = errorMsg;
            }
        }
        void pUpdateRecords(object p, out object err)
        {
            procCode = 2;
            ExpensesEntryCommit inp = (ExpensesEntryCommit)p;

            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);
                db.RecordQuery("SELECT * FROM tblexpenses WHERE fID = '" + inp.id + "'");

                if (db.Count == 1)
                {
                    db.QueryTable.Rows[0]["fExpensesName"] = inp.name;
                    db.QueryTable.Rows[0]["fExpensesAmount"] = inp.amount;
                    db.QueryTable.Rows[0]["fExpensesType"] = inp.type;
                    db.QueryTable.Rows[0]["fDate"] = inp.date;

                    db.Update(ConflictOption.CompareRowVersion);
                    isUpdated = true;
                }
                else
                    isUpdated = false;
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                err = errorMsg;
            }
        }
        void pSearchRecords(object p, out object err)
        {
            string date = (string)p;
            procCode = 3;
            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);
                db.RecordQuery("SELECT * FROM tblexpenses WHERE fDate = '" + date + "'");

                pTable = new DataTable();
                pTable.Columns.Add("Code");
                pTable.Columns.Add("Expenses Description");
                pTable.Columns.Add("Amount");
                pTable.Columns.Add("Type");

                for (int i = 0; i < db.Count; i++)
                {
                    DataRow dr = pTable.NewRow();
                    dr["Code"] = db.RecordAt(i, "fID");
                    dr["Expenses Description"] = db.RecordAt(i, "fExpensesName");
                    dr["Amount"] = db.RecordAt(i, "fExpensesAmount");
                    dr["Type"] = db.RecordAt(i, "fExpensesType");


                    pTable.Rows.Add(dr);
                }

            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                err = errorMsg;
            }
        }

        //online
        void pSearchRecordsOnline(object p, out object err)
        {
            string date = (string)p;
            procCode = 3;
            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.oServer, Common.oDatabase, Common.oUID, Common.oPWD);
                db.RecordQuery("SELECT * FROM tblexpenses WHERE fDate = '" + date + "'");

                pTable = new DataTable();
                pTable.Columns.Add("Code");
                pTable.Columns.Add("Expenses Description");
                pTable.Columns.Add("Amount");
                pTable.Columns.Add("Type");

                for (int i = 0; i < db.Count; i++)
                {
                    DataRow dr = pTable.NewRow();
                    dr["Code"] = db.RecordAt(i, "fID");
                    dr["Expenses Description"] = db.RecordAt(i, "fExpensesName");
                    dr["Amount"] = db.RecordAt(i, "fExpensesAmount");
                    dr["Type"] = db.RecordAt(i, "fExpensesType");


                    pTable.Rows.Add(dr);
                }

            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                err = errorMsg;
            }
        }
        //Async op
        void GenericCB(IAsyncResult ar)
        {
            //Obtain the Delegate
            AsyncOp ao = (AsyncOp)((AsyncResult)ar).AsyncDelegate;
            //Prepare output
            object err;
            //Wrap-up the output
            ao.EndInvoke(out err, ar);
            string er = (string)err;
            if (er.Equals(""))
            {
                OnProcessCompleted(er);
            }
            else
            {
                OnProcessError(er);
            }
        }

        public void GetRecords()
        {
            AsyncOp ao = new AsyncOp(pGetRecords);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object er;
            IAsyncResult ar = ao.BeginInvoke(null, out er, ac, null);
        }
        public void Commit(ExpensesEntryCommit[] eec)
        {
            AsyncOp ao = new AsyncOp(pCommit);
            AsyncCallback ac = new AsyncCallback(GenericCB);


            object er;
            IAsyncResult ar = ao.BeginInvoke(eec, out er, ac, null);
        }
        public void UpdateRecords(ExpensesEntryCommit expenses)
        {
            AsyncOp ao = new AsyncOp(pUpdateRecords);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object er;
            IAsyncResult ar = ao.BeginInvoke(expenses, out er, ac, null);
        }
        public void SearchRecords(string date)
        {
            AsyncOp ao = new AsyncOp(pSearchRecords);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);
            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(date, out er, ac, null);
        }

        //online
        public void SearchRecordsOnline(string date)
        {
            AsyncOp ao = new AsyncOp(pSearchRecordsOnline);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);
            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(date, out er, ac, null);
        }
        public DataTable RecordTable
        {
            get { return pTable; }
        }
        public int ProcessCode
        {
            get { return procCode; }
        }
        public bool Updated
        {
            get { return isUpdated; }
        }
        //Events
        public delegate void MyEventHandler(string msg);
        public event MyEventHandler ProcessCompleted;
        public event MyEventHandler ProcessError;
        protected virtual void OnProcessCompleted(string msg)
        {
            if (ProcessCompleted != null) ProcessCompleted(msg);
        }
        protected virtual void OnProcessError(string msg)
        {
            if (ProcessError != null) ProcessError(msg);
        }
    }
    public class CashRegistered
    {
        int procCode = -1;
        string date = DateTime.Now.Date.ToShortDateString();
        double totalCheckAmount = 0.0f, totalExpensesA = 0.0f, totalExpensesB = 0.0f;
        string over = "";

        bool isSaved = false;
        bool withRecord = false;
        DataTable pTable = new DataTable();
        string errorMsg = "";

        //Sync op
        void pGetRecords(object p, out object er)
        {
            procCode = 0;
            string err = "";

            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);
                //denomination
                db.RecordQuery("SELECT * FROM tbldenomination");

                pTable = new DataTable();
                pTable.Columns.Add("Denomination");
                pTable.Columns.Add("pcs");
                pTable.Columns.Add("Amount");

                for (int i = 0; i < db.Count; i++)
                {
                    DataRow dr = pTable.NewRow();
                    dr["Denomination"] = db.RecordAt(i, "fDenomination");
                    pTable.Rows.Add(dr);
                }

                //check
                double amt = 0.0f;
                totalCheckAmount = 0.0f;

                db.RecordQuery("SELECT * FROM tblcheque WHERE fDateReceived = '" + date + "'");
                for (int i = 0; i < db.Count; i++)
                {
                    amt = double.Parse(db.RecordAt(i, "fAmount").ToString());
                    totalCheckAmount = totalCheckAmount + amt;
                }
                //expenses A
                double amtA = 0.0f;
                totalExpensesA = 0.0f;

                db.RecordQuery("SELECT * FROM tblexpenses WHERE fExpensesType='A' AND fDate = '" + date + "'");
                for (int i = 0; i < db.Count; i++)
                {
                    amtA = double.Parse(db.RecordAt(i, "fExpensesAmount").ToString());
                    totalExpensesA = totalExpensesA + amtA;
                }

                //expenses B
                db.RecordQuery("SELECT * FROM tblexpenses WHERE fExpensesType='B' AND fDate = '" + date + "'");

                double amtB = 0.0f;
                totalExpensesB = 0.0f;

                for (int i = 0; i < db.Count; i++)
                {
                    amtB = double.Parse(db.RecordAt(i, "fExpensesAmount").ToString());
                    totalExpensesB = totalExpensesB + amtB;
                }
            }
            catch (Exception ex)
            {
                err = ex.Message;
            }
            finally
            {
                er = err;
            }
        }
        void pCommit(object p, out object er)
        {
            procCode = 1;
            CashRegistryCommit[] inp = (CashRegistryCommit[])p;
            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);

                db.RecordQuery("SELECT * FROM tblcashregistry WHERE fDate = '" + inp[0].fDate + "'");
                if (db.Count == 0)
                {
                    for (int i = 0; i < inp.Length; i++)
                    {
                        DataRow dr = db.QueryTable.NewRow();
                        dr["fDate"] = inp[i].fDate;
                        dr["fDenomination"] = inp[i].fDenomination;
                        dr["fPcs"] = inp[i].fPcs;
                        dr["fOver"] = inp[i].fOver;

                        db.AddRecord(dr);
                        db.Update();
                    }
                    isSaved = true;
                }
                else
                    isSaved = false;
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                er = errorMsg;
            }
        }
        void pSearchRecords(object p, out object er)
        {
            procCode = 2;
            string err = "";
            string date = (string)p;
            double dtype = 0, pcs = 0, amount = 0;

            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.lServer, Common.lDatabase, Common.lUID, Common.lPWD);
                //denomination
                db.RecordQuery("SELECT * FROM tblcashregistry WHERE fDate = '" + date + "'");
                if (db.Count > 0)
                {
                    pTable = new DataTable();
                    pTable.Columns.Add("Denomination");
                    pTable.Columns.Add("pcs");
                    pTable.Columns.Add("Amount");


                    for (int i = 0; i < db.Count; i++)
                    {
                        DataRow dr = pTable.NewRow();
                        dr["Denomination"] = db.RecordAt(i, "fDenomination");
                        dr["pcs"] = db.RecordAt(i, "fPcs");

                        if (db.RecordAt(i, "fDenomination").Equals("Coins"))
                            dtype = 1;
                        else
                            dtype = double.Parse(db.RecordAt(i, "fDenomination"));

                        pcs = double.Parse(db.RecordAt(i, "fPcs"));
                        amount = dtype * pcs;

                        dr["Amount"] = Common.FormatCurrency(amount).ToString();

                        pTable.Rows.Add(dr);
                    }
                    over = db.RecordAt(0, "fOver");
                    if (over == "")
                        over = "0";
                    //check
                    double amt = 0.0f;
                    totalCheckAmount = 0.0f;

                    db.RecordQuery("SELECT * FROM tblcheque WHERE fDateReceived = '" + date + "'");
                    for (int i = 0; i < db.Count; i++)
                    {
                        amt = double.Parse(db.RecordAt(i, "fAmount").ToString());
                        totalCheckAmount = totalCheckAmount + amt;
                    }
                    //expenses A
                    double amtA = 0.0f;
                    totalExpensesA = 0.0f;

                    db.RecordQuery("SELECT * FROM tblexpenses WHERE fExpensesType='A' AND fDate = '" + date + "'");
                    for (int i = 0; i < db.Count; i++)
                    {
                        amtA = double.Parse(db.RecordAt(i, "fExpensesAmount").ToString());
                        totalExpensesA = totalExpensesA + amtA;
                    }

                    //expenses B
                    db.RecordQuery("SELECT * FROM tblexpenses WHERE fExpensesType='B' AND fDate = '" + date + "'");

                    double amtB = 0.0f;
                    totalExpensesB = 0.0f;

                    for (int i = 0; i < db.Count; i++)
                    {
                        amtB = double.Parse(db.RecordAt(i, "fExpensesAmount").ToString());
                        totalExpensesB = totalExpensesB + amtB;
                    }
                    withRecord = true;
                }
                else
                    withRecord = false;
            }
            catch (Exception ex)
            {
                err = ex.Message;
            }
            finally
            {
                er = err;
            }
        }

        //online
        void pSearchRecordsOnline(object p, out object er)
        {
            procCode = 2;
            string err = "";
            string date = (string)p;
            double dtype = 0, pcs = 0, amount = 0;

            try
            {
                uDatabase db = new uDatabase();
                db.Connect(OdbcVersion.v510, Common.oServer, Common.oDatabase, Common.oUID, Common.oPWD);
                //denomination
                db.RecordQuery("SELECT * FROM tblcashregistry WHERE fDate = '" + date + "'");
                if (db.Count > 0)
                {
                    pTable = new DataTable();
                    pTable.Columns.Add("Denomination");
                    pTable.Columns.Add("pcs");
                    pTable.Columns.Add("Amount");


                    for (int i = 0; i < db.Count; i++)
                    {
                        DataRow dr = pTable.NewRow();
                        dr["Denomination"] = db.RecordAt(i, "fDenomination");
                        dr["pcs"] = db.RecordAt(i, "fPcs");

                        if (db.RecordAt(i, "fDenomination").Equals("Coins"))
                            dtype = 1;
                        else
                            dtype = double.Parse(db.RecordAt(i, "fDenomination"));

                        pcs = double.Parse(db.RecordAt(i, "fPcs"));
                        amount = dtype * pcs;

                        dr["Amount"] = Common.FormatCurrency(amount).ToString();

                        pTable.Rows.Add(dr);
                    }
                    over = db.RecordAt(0, "fOver");
                    if (over == "")
                        over = "0";
                    //check
                    double amt = 0.0f;
                    totalCheckAmount = 0.0f;

                    db.RecordQuery("SELECT * FROM tblcheque WHERE fDateReceived = '" + date + "'");
                    for (int i = 0; i < db.Count; i++)
                    {
                        amt = double.Parse(db.RecordAt(i, "fAmount").ToString());
                        totalCheckAmount = totalCheckAmount + amt;
                    }
                    //expenses A
                    double amtA = 0.0f;
                    totalExpensesA = 0.0f;

                    db.RecordQuery("SELECT * FROM tblexpenses WHERE fExpensesType='A' AND fDate = '" + date + "'");
                    for (int i = 0; i < db.Count; i++)
                    {
                        amtA = double.Parse(db.RecordAt(i, "fExpensesAmount").ToString());
                        totalExpensesA = totalExpensesA + amtA;
                    }

                    //expenses B
                    db.RecordQuery("SELECT * FROM tblexpenses WHERE fExpensesType='B' AND fDate = '" + date + "'");

                    double amtB = 0.0f;
                    totalExpensesB = 0.0f;

                    for (int i = 0; i < db.Count; i++)
                    {
                        amtB = double.Parse(db.RecordAt(i, "fExpensesAmount").ToString());
                        totalExpensesB = totalExpensesB + amtB;
                    }
                    withRecord = true;
                }
                else
                    withRecord = false;
            }
            catch (Exception ex)
            {
                err = ex.Message;
            }
            finally
            {
                er = err;
            }
        }
        //Async op
        void GenericCB(IAsyncResult ar)
        {
            //Obtain the Delegate
            AsyncOp ao = (AsyncOp)((AsyncResult)ar).AsyncDelegate;
            //Prepare output
            object err;
            //Wrap-up the output
            ao.EndInvoke(out err, ar);
            string er = (string)err;
            if (er.Equals(""))
            {
                OnProcessCompleted(er);
            }
            else
            {
                OnProcessError(er);
            }
        }

        public void GetRecords()
        {
            //Synchronous method to call.
            AsyncOp ao = new AsyncOp(pGetRecords);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);
            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(null, out er, ac, null);

        }
        public void Commit(CashRegistryCommit[] crm)
        {
            //Synchronous method to call.
            AsyncOp ao = new AsyncOp(pCommit);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);
            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(crm, out er, ac, null);

        }
        public void SearchRecord(string date)
        {
            //Synchronous method to call.
            AsyncOp ao = new AsyncOp(pSearchRecords);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);
            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(date, out er, ac, null);

        }

        //online
        public void SearchRecordOnline(string date)
        {
            //Synchronous method to call.
            AsyncOp ao = new AsyncOp(pSearchRecordsOnline);
            //Async Callback
            AsyncCallback ac = new AsyncCallback(GenericCB);
            //Prepare out
            object er;
            //Call the Synchronous Method
            IAsyncResult ar = ao.BeginInvoke(date, out er, ac, null);

        }
        //return
        public DataTable RecordTable
        {
            get { return pTable; }
        }
        public int ProcessCode
        {
            get { return procCode; }
        }
        public double totalCheck
        {
            get { return totalCheckAmount; }
        }
        public double totalExA
        {
            get { return totalExpensesA; }
        }
        public double totalExB
        {
            get { return totalExpensesB; }
        }
        public string overAmt
        {
            get { return over; }
        }
        public bool foundRecord
        {
            get { return withRecord; }
        }
        public bool Saved
        {
            get { return isSaved; }
        }
        //Events
        public delegate void EventHandler(string msg);
        public event EventHandler ProcessCompleted;
        public event EventHandler ProcessError;

        protected virtual void OnProcessCompleted(string msg)
        {
            if (ProcessCompleted != null) ProcessCompleted(msg);
        }
        protected virtual void OnProcessError(string msg)
        {
            if (ProcessError != null) ProcessError(msg);
        }
    }


    static class General
    {
        public static MBBStoreClient.frmMain parent;
    }
}